#include <WiFi.h>
#include <TFT_eSPI.h>

#define BLK 5
#define LED_PIN 2
#define PORT 8765
#define WIDTH 240
#define HEIGHT 240
#define BLOCK_LINES 80
#define BLOCK_SIZE (WIDTH * BLOCK_LINES * 2)
#define TAIL_BYTE_1 0xAA
#define TAIL_BYTE_2 0xBB
#define TAIL_BYTE_3 0xCC

const char* ssid = "helloworld";
const char* password = "12345678";

WiFiServer server(PORT);
WiFiClient client;

TFT_eSPI tft = TFT_eSPI();
static uint8_t block_buffer[BLOCK_SIZE + 3];

// 异步闪灯任务
// void ledTask(void *pvParameters) {
//   //设置 GPIO2 为输出引脚 随时电死人
//   pinMode(LED_PIN, OUTPUT);
//   while (true) {
//     digitalWrite(LED_PIN, HIGH);
//     // vTaskDelay() 用于让 当前任务挂起指定时间，相当于“睡眠”，但是不会阻塞整个 CPU，只会暂停这个任务，让其他任务可以运行。
//     vTaskDelay(500 / portTICK_PERIOD_MS);
//     digitalWrite(LED_PIN, LOW);
//     vTaskDelay(500 / portTICK_PERIOD_MS);
//   }
//  }

void showStartupMessage() {
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  uint8_t textSize = 2;
  tft.setTextSize(textSize);
  String msg = "hello python";

  int16_t w = msg.length() * 6 * textSize;
  int16_t h = 8 * textSize;
  int16_t x = (WIDTH - w) / 2;
  int16_t y = (HEIGHT - h) / 2;

  tft.setCursor(x, y);
  tft.print(msg);
}

void setup() {
  Serial.begin(115200);
  //---------------------
  // 工作灯运行
  //---------------------
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  tft.init();
  tft.setRotation(2);
  tft.setSwapBytes(true);
  tft.invertDisplay(true);

  pinMode(BLK, OUTPUT);
  digitalWrite(BLK, LOW);
  showStartupMessage();

  // WiFi
  WiFi.begin(ssid, password);
  Serial.print("连接 WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n✅ WiFi 已连接！");
  Serial.println(WiFi.localIP());

  digitalWrite(BLK, HIGH);
  server.begin();

  //  创建 LED 异步任务
//   xTaskCreate(
//     ledTask,      // 任务函数
//     "LED Blink",  // 任务名
//     1024,         // 栈大小
//     NULL,         // 参数
//     1,            // 优先级
//     NULL          // 任务句柄
//   );
}

void loop() {
  if (!client || !client.connected()) {
    client = server.available();
    if (client) Serial.println("客户端已连接！");
    return;
  }

  static size_t received = 0;
  static int y_pos = 0;
  static uint8_t tail[3];

  while (client.available() && received < BLOCK_SIZE + 3) {
    int read_bytes = client.read(block_buffer + received, BLOCK_SIZE + 3 - received);
    if (read_bytes > 0) received += read_bytes;
  }

  if (received < BLOCK_SIZE + 3) return;

  memcpy(tail, block_buffer + BLOCK_SIZE, 3);

  if (tail[0] != TAIL_BYTE_1 || tail[1] != TAIL_BYTE_2 || tail[2] != TAIL_BYTE_3) {
    client.write("error");
    received = 0;
    return;
  }

  if (y_pos == 0) tft.fillScreen(TFT_BLACK);
  tft.pushImage(0, y_pos, WIDTH, BLOCK_LINES, (uint16_t*)block_buffer);
  y_pos += BLOCK_LINES;
  if (y_pos >= HEIGHT) y_pos = 0;

  client.write("ok");
  received = 0;
}